package cn.pugle.datasketches;

import com.yahoo.sketches.quantiles.DoublesSketch;
import com.yahoo.sketches.quantiles.UpdateDoublesSketch;
import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;

/**
 * https://datasketches.github.io/docs/Quantiles/QuantilesOverview.html
 *
 * @author tzp
 * @since 2019/7/2
 */
public class Quantiles {
    public static final String DATA = "/Users/tzp/Documents/private/cnm/CodeAccumulate/target/data";

    public static void main(String[] args) throws IOException {
//        genGaussian(DATA, 100 * 10000, 0, 10);
//        histogram(DATA, 128);
        histogram("/Users/tzp/Documents/private/cnm/CodeAccumulate/target/score", 8);
    }

    public static void histogram(String file, int k) throws IOException {
        int numOfGram = 40;

        BufferedReader br = new BufferedReader(new FileReader(file));
        String line;
        UpdateDoublesSketch qs = DoublesSketch.builder()
                .setK(k)
                .build();
        //load the sketch
        while ((line = br.readLine()) != null) {
            Double value = Double.valueOf(line);
            qs.update(value);
        }

        //使用quantiles获取分位点
        //long n = qs.getN();
        double[] fRanks = {0.01, 0.99};
        double[] quantiles = qs.getQuantiles(fRanks);

        //根据两个分位点的值, 分成40段
        double[] splitPoints = new double[numOfGram + 1];
        splitPoints[0] = quantiles[0];
        double step = (quantiles[1] - quantiles[0]) / numOfGram;
        for (int j = 1; j <= numOfGram; j++) {
            splitPoints[j] = quantiles[0] + step * j;
        }
        //使用pmf获取各个段的概率密度
        double[] fractionalRanks = qs.getPMF(splitPoints);
        int bins = fractionalRanks.length;

        //画一个直方图
        double max = Arrays.stream(fractionalRanks).max().getAsDouble();
        for (int i = 0; i < bins; i++) {
            int x = (int) (fractionalRanks[i] / max * 100);
            System.out.println(StringUtils.repeat("*", x));
        }
        System.out.println(qs.toString());
    }

}
